home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifcico / zmrle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-09  |  4.5 KB  |  193 lines

  1. /*
  2.  * File: zmr.c 07-30-1989
  3.  * Copyright 1988, 1989 Omen Technology Inc All Rights Reserved
  4.  *
  5.  *
  6.  * 
  7.  * This module implements ZMODEM Run Length Encoding, an
  8.  * extension that was not funded by the original Telenet
  9.  * development contract.
  10.  * 
  11.  * This software may be freely used for non commercial and
  12.  * educational (didactic only) purposes.  This software may also
  13.  * be freely used to support file transfer operations to or from
  14.  * licensed Omen Technology products.  Any programs which use
  15.  * part or all of this software must be provided in source form
  16.  * with this notice intact except by written permission from Omen
  17.  * Technology Incorporated.
  18.  * 
  19.  * Use of this software for commercial or administrative purposes
  20.  * except when exclusively limited to interfacing Omen Technology
  21.  * products requires a per port license payment of $20.00 US per
  22.  * port (less in quantity).  Use of this code by inclusion,
  23.  * decompilation, reverse engineering or any other means
  24.  * constitutes agreement to these conditions and acceptance of
  25.  * liability to license the materials and payment of reasonable
  26.  * legal costs necessary to enforce this license agreement.
  27.  *
  28.  *
  29.  *        Omen Technology Inc        FAX: 503-621-3745
  30.  *        Post Office Box 4681
  31.  *        Portland OR 97208
  32.  *
  33.  *    This code is made available in the hope it will be useful,
  34.  *    BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
  35.  *    DAMAGES OF ANY KIND.
  36.  *
  37.  *    ZMODEM RLE compression and decompression functions
  38.  */
  39.  
  40. #include "lutil.h"
  41. #include "ttyio.h"
  42. #include "zmodem.h"
  43.  
  44. static char *badcrc="Bad CRC";
  45.  
  46. /* Send data subpacket RLE encoded with 32 bit FCS */
  47. void zsdar32(buf, length, frameend)
  48. char *buf;
  49. int length,frameend;
  50. {
  51.     register int c, l, n;
  52.     register long crc;
  53.  
  54.     crc = 0xFFFFFFFFL;  l = *buf++ & 0377;
  55.     if (length == 1) {
  56.         zsendline(l); crc = updcrc32(l, crc);
  57.         if (l == ZRESC) {
  58.             zsendline(1); crc = updcrc32(1, crc);
  59.         }
  60.     } else {
  61.         for (n = 0; --length >= 0; ++buf) {
  62.             if ((c = *buf & 0377) == l && n < 126 && length>0) {
  63.                 ++n;  continue;
  64.             }
  65.             switch (n) {
  66.             case 0:
  67.                 zsendline(l);
  68.                 crc = updcrc32(l, crc);
  69.                 if (l == ZRESC) {
  70.                     zsendline(0100); crc = updcrc32(0100, crc);
  71.                 }
  72.                 l = c; break;
  73.             case 1:
  74.                 if (l != ZRESC) {
  75.                     zsendline(l); zsendline(l);
  76.                     crc = updcrc32(l, crc);
  77.                     crc = updcrc32(l, crc);
  78.                     n = 0; l = c; break;
  79.                 }
  80.                 /* **** FALL THRU TO **** */
  81.             default:
  82.                 zsendline(ZRESC); crc = updcrc32(ZRESC, crc);
  83.                 if (l == 040 && n < 34) {
  84.                     n += 036;
  85.                     zsendline(n); crc = updcrc32(n, crc);
  86.                 }
  87.                 else {
  88.                     n += 0101;
  89.                     zsendline(n); crc = updcrc32(n, crc);
  90.                     zsendline(l); crc = updcrc32(l, crc);
  91.                 }
  92.                 n = 0; l = c; break;
  93.             }
  94.         }
  95.     }
  96.     PUTCHAR(ZDLE); PUTCHAR(frameend);
  97.     crc = updcrc32(frameend, crc);
  98.  
  99.     crc = ~crc;
  100.     for (length=4; --length >= 0;) {
  101.         zsendline((int)crc);  crc >>= 8;
  102.     }
  103. }
  104.  
  105.  
  106. /* Receive data subpacket RLE encoded with 32 bit FCS */
  107. int zrdatr32(buf, length)
  108. register char *buf;
  109. int length;
  110. {
  111.     register int c;
  112.     register long crc;
  113.     register char *end;
  114.     register int d;
  115.  
  116.     crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
  117.     d = 0;    /* Use for RLE decoder state */
  118.     while (buf <= end) {
  119.         if ((c = zdlread()) & ~0377) {
  120. crcfoo:
  121.             switch (c) {
  122.             case GOTCRCE:
  123.             case GOTCRCG:
  124.             case GOTCRCQ:
  125.             case GOTCRCW:
  126.                 d = c;  c &= 0377;
  127.                 crc = updcrc32(c, crc);
  128.                 if ((c = zdlread()) & ~0377)
  129.                     goto crcfoo;
  130.                 crc = updcrc32(c, crc);
  131.                 if ((c = zdlread()) & ~0377)
  132.                     goto crcfoo;
  133.                 crc = updcrc32(c, crc);
  134.                 if ((c = zdlread()) & ~0377)
  135.                     goto crcfoo;
  136.                 crc = updcrc32(c, crc);
  137.                 if ((c = zdlread()) & ~0377)
  138.                     goto crcfoo;
  139.                 crc = updcrc32(c, crc);
  140.                 if (crc != 0xDEBB20E3) {
  141.                     loginf(badcrc);
  142.                     return ERROR;
  143.                 }
  144.                 Rxcount = length - (end - buf);
  145.  
  146.                 debug(11,"zrdatr32: %d %s", Rxcount,
  147.                   Zendnames[(d-GOTCRCE)&3]);
  148.  
  149.                 return d;
  150.             case GOTCAN:
  151.                 loginf("Sender Canceled");
  152.                 return ZCAN;
  153.             case TIMEOUT:
  154.                 loginf("TIMEOUT");
  155.                 return c;
  156.             default:
  157.                 loginf("Bad data subpacket");
  158.                 return c;
  159.             }
  160.         }
  161.         crc = updcrc32(c, crc);
  162.         switch (d) {
  163.         case 0:
  164.             if (c == ZRESC) {
  165.                 d = -1;  continue;
  166.             }
  167.             *buf++ = c;  continue;
  168.         case -1:
  169.             if (c >= 040 && c < 0100) {
  170.                 d = c - 035; c = 040;  goto spaces;
  171.             }
  172.             if (c == 0100) {
  173.                 d = 0;
  174.                 *buf++ = ZRESC;  continue;
  175.             }
  176.             d = c;  continue;
  177.         default:
  178.             d -= 0100;
  179.             if (d < 1)
  180.                 goto badpkt;
  181. spaces:
  182.             if ((buf + d) > end)
  183.                 goto badpkt;
  184.             while ( --d >= 0)
  185.                 *buf++ = c;
  186.             d = 0;  continue;
  187.         }
  188.     }
  189. badpkt:
  190.     loginf("Data subpacket too long");
  191.     return ERROR;
  192. }
  193.